package com.xebest.web.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xebest.common.enums.erp.aftersales.VenAfterSaleStatusEnum;
import com.xebest.common.enums.erp.aftersales.VenOrderRefundStatusEnum;
import com.xebest.common.enums.erp.aftersales.VenOrderRefundTypeEnum;
import com.xebest.common.enums.erp.order.VenOrderPayChannelEnum;
import com.xebest.util.Money;
import com.xebest.web.form.XeVenAfterSaleCheckForm;
import com.xebest.web.form.XeVenAfterSaleDelForm;
import com.xebest.web.form.XeVenAfterSaleDetailForm;
import com.xebest.web.form.XeVenOrderRefundQueryForm;
import com.xebest.web.mapper.read.XeVenAfterSaleDetailReadMapper;
import com.xebest.web.mapper.read.XeVenOrderRefundReadMapper;
import com.xebest.web.mapper.write.XeVenOrderRefundWriteMapper;
import com.xebest.web.model.XeVenAfterSaleDetailEntity;
import com.xebest.web.model.XeVenAfterSaleEntity;
import com.xebest.web.model.XeVenOrderInfoDetailEntity;
import com.xebest.web.model.XeVenOrderInfoEntity;
import com.xebest.web.model.XeVenOrderRefundEntity;
import com.xebest.web.service.XeVenAfterSaleService;
import com.xebest.web.service.XeVenEpayService;
import com.xebest.web.service.XeVenOrderReFundService;
import com.xebest.web.service.XeVenOrderService;
import com.xebest.web.view.XeVenAfterSaleDetailView;
import com.xebest.web.view.XeVenOrderRefundView;
import com.xebest.web.view.XeVenRejectRefundDetailView;

import net.sf.json.JSONObject;

/**
 * @desc:
 * @author: chenjing
 * @createTime: 2017/6/22 0022 下午 7:31
 * @history:
 * @version:v1.0
 */
@Service
public class XeVenOrderReFundServiceImpl implements XeVenOrderReFundService {
    private static Logger log = LoggerFactory.getLogger(XeVenOrderReFundServiceImpl.class);

    @Autowired
    XeVenOrderRefundReadMapper readMapper;
    @Autowired
    XeVenOrderRefundWriteMapper writeMapper;
    @Autowired
    XeVenAfterSaleDetailReadMapper afterSaleDetailReadMapper;
    @Autowired
    XeVenEpayService epayService;
    @Autowired
    XeVenOrderService orderService;
    @Autowired
    XeVenAfterSaleService afterSaleService;

    /**
     * @Author:chenjing
     * @Description:根据订单号查询已退款金额
     * @Date:下午 7:31 2017/6/22 0022
     * @params: * @param null
     * @return:
     */
    @Override
    public BigDecimal getRefundEdAmountByOrderId(String orderId,String userCode) {
        return readMapper.getRefundEdAmountByOrderId(orderId,userCode);
    }

    /**
     * @Author:chenjing
     * @Description: 根据退款号查询退款单信息
     * @Date:下午 5:29 2017/6/27 0027
     * @params: * @param null
     * @return:
     */
    @Override
    public XeVenOrderRefundEntity getOrderRefundByRefundCode(String orderRefundCode, String userCode) {
        return readMapper.selectByRefundCode(orderRefundCode, userCode);
    }

    /**
     * @Author:chenjing
     * @Description:审核 更新退款单信息
     * @Date:下午 5:40 2017/6/27 0027
     * @params: * @param null
     * @return:
     */
    @Transactional(value="writeTransactionManager")
    @Override
    public int updateOrderRefund(XeVenOrderRefundEntity entity) throws Exception {
        int refundStatus = entity.getRefundStatus();
        int refundType = entity.getRefundType();
        int flag = 0;
        /**
         * 如果拒绝退款则更新售后单
         */
        if(VenOrderRefundStatusEnum.BACKED.getValue().equals(refundStatus)
                && (VenOrderRefundTypeEnum.AFTERSALEREJECT.getValue().equals(refundType)
                  || VenOrderRefundTypeEnum.AFTERSALERFUND.getValue().equals(refundType))){

            //更新售后单状态为已作废
            XeVenAfterSaleEntity afterSaleEntity = afterSaleService.selectByPrimaryKey(entity.getAfterSalesCode(),entity.getUserCode());
            if (null == afterSaleEntity){
                log.error("更新售后单状态异常，结果为空，售后单id={}", entity.getAfterSalesCode());
                throw  new RuntimeException();
            }
            afterSaleEntity.setAfterSaleStatus(VenAfterSaleStatusEnum.CANCELED.getValue());
            afterSaleEntity.setModifyUser(entity.getModifyUser());
            afterSaleEntity.setCancelUser(entity.getModifyUser());
            afterSaleEntity.setCancelReason("拒绝退款");
            flag =  afterSaleService.updateByPrimaryKey(afterSaleEntity);
            if (flag==0){
                log.error("退款单更新异常，结果为空，退款单id={}", entity.getRefundCode());
                throw  new RuntimeException();
            }
            //// TODO: 2017/9/12  插入售后单更新日志
        }
        //更新退款单信息
        flag = writeMapper.updateByOrderRefundInfo(entity);
        // TODO: 2017/6/29 0029 插入退款单更新日志
        return flag;
    }

    /**
     * @Author:chenjing
     * @Description:查询退款单列表
     * @Date:下午 4:27 2017/6/28 0028
     * @params: * @param null
     * @return:
     */
    @Override
    public List<XeVenOrderRefundView> getOrderRefundList(XeVenOrderRefundQueryForm form) throws Exception {
        return readMapper.getOrderRefundList(form);
    }

    /**
     * @Author:chenjing
     * @Description:批量审核退款单
     * @Date:下午 4:05 2017/7/6 0006
     * @params: * @param null
     * @return:
     */
    @Override
    public int batchOrderRefundList(XeVenAfterSaleCheckForm form) throws Exception {
        return writeMapper.batchOrderRefundList(form);
    }

    /**
     * @Author:chenjing
     * @Description:根据退款单号查询退款单详细信息
     * @Date:下午 4:05 2017/7/6 0006
     * @params: * @param null
     * @return:
     */
    @Override
    public List<XeVenAfterSaleDetailView> queryRefundDetail(XeVenAfterSaleDetailForm form) {
        List<XeVenAfterSaleDetailView> viewList = new ArrayList<>();
        if(StringUtils.isNotBlank(form.getAfterSalesCode())){
            //获取各个商品的已退款金额
            List<XeVenRejectRefundDetailView> rrd =
                    afterSaleDetailReadMapper.queryRejectRefundDetail(form.getOrderId(),form.getUserCode(),"");
            //查询售后单明细
            List<XeVenAfterSaleDetailEntity> detailList =
                    afterSaleDetailReadMapper.queryAfterSaleDetailList(form.getAfterSalesCode());
            for (XeVenAfterSaleDetailEntity entity:detailList){
                XeVenAfterSaleDetailView view = JSON.parseObject(JSON.toJSONString(entity, SerializerFeature.WriteMapNullValue,
                        SerializerFeature.WriteNullStringAsEmpty),XeVenAfterSaleDetailView.class);
                for (XeVenRejectRefundDetailView rrdView : rrd) {
                    if (view.getProSku().equals(rrdView.getProSku())) {
                        view.setRealRefundAmount(rrdView.getRealRefundAmount());

                    }
                }
                viewList.add(view);
            }

        }else {
            Map orderServiceMap = new HashMap();
            orderServiceMap.put("orderId", form.getOrderId());
            orderServiceMap.put("userCode", form.getUserCode());
            //获取订单明细信息
            List<XeVenOrderInfoDetailEntity> orderInfoDetailList = orderService.getOrderDetailByParam(orderServiceMap);
            for (XeVenOrderInfoDetailEntity detailEntity:orderInfoDetailList){
                XeVenAfterSaleDetailView view = JSON.parseObject(JSON.toJSONString(detailEntity),XeVenAfterSaleDetailView.class);
                view.setRealRefundAmount(new BigDecimal(0));
                view.setRejectAmount(detailEntity.getDifferenceAmount());
                viewList.add(view);
            }
        }
        // List<XeVenOrderRefundDetailEntity> entityList = readMapper.queryRefundAmountByOrderId(form.getOrderId(), "");
        return viewList;
    }

    /**
     * @Author:chenjing
     * @Description:批量删除退款单信息
     * @Date:上午 11:23 2017/7/7 0007
     * @params: * @param null
     * @return:
     */
    @Override
    public int delRefundList(XeVenAfterSaleDelForm form) {
        return writeMapper.delRefundList(form);
    }

    /**
     * @Author:chenjing
     * @Description:确认退款微信退款(批量) （已不用）
     * @Date:14:51 2017/8/5
     * @params: * @param null
     * @return:
     */
    @Override
    public Map refundAllByWxPay(XeVenAfterSaleDelForm form) throws Exception{
        int flag = 0; //数据库处理结果
        int okSum = 0; //成功条数
        int errSum = 0; //失败条数
        Map map  = new HashedMap();
        int [] payChannel ={VenOrderPayChannelEnum.WECHAT.getValue()}; //支付渠道 = 微信支付
        List<XeVenOrderRefundEntity> list =
                readMapper.queryRefundByCodes(form.getRefundFormCodes(),form.getUserCode(),
                        VenOrderRefundStatusEnum.CHECKED.getValue(),payChannel);
        JSONObject json = new JSONObject();
            for (XeVenOrderRefundEntity entity:list){
                log.info("微信退款请求易支付开始：订单号={}，退款单号={}，退款金额={}",entity.getOrderId(),entity.getRefundCode(),entity.getRealRefundedAmount().toString());
                String str =
                        epayService.refundMoneyByWebChat(entity.getOrderId(),entity.getRefundCode(),entity.getRealRefundedAmount().toString(),
                        		entity.getRefundType());
                log.info("微信退款请求易支付返回结果：{}",str);
                if (null != str){
                    json = JSONObject.fromObject(str);
                    if(json.get("resultCode").toString().equals("0000")){
                        //如果退款成功，更新退款单状态
                        entity.setRefundStatus(VenOrderRefundStatusEnum.DOING.getValue());
                        flag = writeMapper.updateByOrderRefundInfo(entity);
                        //更新成功 ，增加成功条数，失败增加失败条数
                        if(flag>0){
                            okSum ++;
                        }else {
                            errSum ++;
                        }
                    }else {
                        //退款失败
//                        entity.setRefundStatus(VenOrderRefundStatusEnum.FAILED.getValue());
//                        flag = writeMapper.updateByOrderRefundInfo(entity,form.getUserCode());
                        errSum ++;
                    }
                }else {
                    errSum ++;
                }
            }
            map.put("okSum",okSum);
            map.put("errSum",errSum);
        return map;
    }


    /**
     * @Author:chenjing
     * @Description:批量退款（非微信支付）-- 已作废
     * @Date:10:48 2017/8/7
     * @params: * @param
     * @return:
     */
    @Override
    public Map refundAllByOnlinePay(XeVenAfterSaleDelForm form) throws Exception {
        int flag = 0; //数据库处理结果
        int okSum = 0; //成功条数
        int errSum = 0; //失败条数
        Map map  = new HashedMap();
        int [] payChannel ={VenOrderPayChannelEnum.ALIPAY.getValue(),VenOrderPayChannelEnum.EPAY.getValue(),VenOrderPayChannelEnum.ONLINE_BANK.getValue()}; //支付渠道 = 非微信支付
        List<XeVenOrderRefundEntity> list =
                readMapper.queryRefundByCodes(form.getRefundFormCodes(),form.getUserCode(),
                        VenOrderRefundStatusEnum.CHECKED.getValue(),payChannel);
        JSONObject json = new JSONObject();
        for (XeVenOrderRefundEntity entity:list){
            //查询订单相关信息
            XeVenOrderInfoEntity orderInfo = afterSaleService.queryOrderInfoByOrderId(entity.getOrderId(),entity.getUserCode());
            log.info("退款（非微信支付）请求易支付开始：订单号={}，买家易支付账号={}，退款单号={}，退款金额={}",
                    orderInfo.getMainOrderId(),orderInfo.getLoginAccount(),entity.getRefundCode(),entity.getRealRefundedAmount().toString());
            String str =
                    epayService.refundMoney(orderInfo.getOrderId(),orderInfo.getLoginAccount(),
                    		entity.getRefundCode(),entity.getRealRefundedAmount().toString(),entity.getRefundType());
           log.info("退款（非微信支付）易支付返回结果：str={}",str);
            if (null != str){
                json = JSONObject.fromObject(str);
                if(json.get("resultCode").toString().equals("0000")){
                    //如果退款成功，更新退款单状态
                    entity.setRefundStatus(VenOrderRefundStatusEnum.DOING.getValue());
                    flag = writeMapper.updateByOrderRefundInfo(entity);
                    //更新成功 ，增加成功条数，失败增加失败条数
                    if(flag>0){
                        okSum ++;
                    }else {
                        errSum ++;
                    }
                }else {
                    //退款失败
//                    entity.setRefundStatus(VenOrderRefundStatusEnum.FAILED.getValue());
//                    flag = writeMapper.updateByOrderRefundInfo(entity,form.getUserCode());
                    errSum ++;
                }
            }else {
                errSum ++;
            }
        }
        map.put("okSum",okSum);
        map.put("errSum",errSum);
        return map;
    }


    /**
     * @Author:chenjing
     * @Description:手动同步状态(非微信支付)--暂不能使用
     * @Date:10:49 2017/8/7
     * @params: * @param null
     * @return:
     */
    @Override
    public boolean queryRefundMoneyDetail(XeVenOrderRefundEntity entity) throws Exception {
        int flag = 0; //数据库处理结果
        boolean okSum = false; //是否退款成功
        JSONObject json = new JSONObject();
        log.info("手动同步状态请求易支付开始：订单号={}，退款单号={}",entity.getOrderId(),entity.getRefundCode());
        String str =
                epayService.queryRefundMoneyDetail(entity.getOrderId(),entity.getRefundCode());
        log.info("手动同步接口易支付返回结果,str={}",str);
        if (null != str){
            /**
            if(str.contains("504")){
                log.error("手动同步接口易支付外部接口异常！");
                return okSum;
            }
             **/
            json = JSONObject.fromObject(str);
            if(json.get("resultCode").toString().equals("0000")){
                //如果退款成功，更新退款单状态
                entity.setRefundStatus(VenOrderRefundStatusEnum.DOING.getValue());
                entity.setRefundDate(new Date());
                flag = writeMapper.updateByOrderRefundInfo(entity);
                //更新成功
                if(flag>0){
                    okSum = true;
                }
            }
        }
        return okSum;
    }

    /**
     * @Author:chenjing
     * @Description:微信支付手动同步状态
     * @Date:16:36 2017/8/7
     * @params: * @param null
     * @return:
     */
    @Override
    public Map queryRefundMoneyDetailByWxPay(XeVenOrderRefundEntity entity) throws Exception {
        int flag = 0; //数据库处理结果
        boolean okFlag = false; //是否退款成功 1=失败 2=成功
        JSONObject json = new JSONObject();
        Map map = new HashedMap();
        log.info("手动同步状态(微信支付)请求易支付开始：订单号={}，退款单号={}",entity.getOrderId(),entity.getRefundCode());
        String refundCode =  entity.getRefundCode(); //退款单号
        String str =
                epayService.queryRefundMoneyByWebChat(entity.getRefundCode());
        log.info("手动同步接口（微信支付）易支付返回结果,str={}",str);
        if (null != str){
            /**
            if(str.contains("504")){
                log.error("手动同步接口（微信支付）易支付外部接口异常！");
                map.put("msg","同步失败！");
                map.put("okSum","1");
                return map;
            }
             **/
            json = JSONObject.fromObject(str);
            if(json.get("resultCode").toString().equals("0000") && refundCode.equals(JSONObject.fromObject(json.get("data")).get("merOrderId"))){
                String status = JSONObject.fromObject(json.get("data")).get("status").toString();
                if ("1".equals(status)){
                    //如果退款成功，更新退款单状态
                    entity.setRefundStatus(VenOrderRefundStatusEnum.DONE.getValue());
                    entity.setRefundDate(new Date());
                    flag = writeMapper.updateByOrderRefundInfo(entity);
                    //更新成功
                    if(flag>0) {
                        map.put("msg","退款成功！");
                        map.put("okSum","2");
                    }else {
                        map.put("msg","更新失败！");
                        map.put("okSum","1");
                    }
                }else if("2".equals(status)){
                    //处理中
                    map.put("msg","退款处理中！");
                    map.put("okSum","2");
                }else if("3".equals(status)){
                    //退款失败
                    entity.setRefundStatus(VenOrderRefundStatusEnum.FAILED.getValue());
                    flag = writeMapper.updateByOrderRefundInfo(entity);
                    //更新成功
                    if(flag>0) {
                        map.put("msg","退款成功！");
                        map.put("okSum","2");
                    }else {
                        map.put("msg","更新失败！");
                        map.put("okSum","1");
                    }
                }
            }
        }
        return map;
    }

    /**
     * @Author:chenjing
     * @Description: 微信退款 单条
     * @Date:10:51 2017/8/7
     * @params: * @param null
     * @return:
     */
    @Override
    public boolean refundByWxPay(XeVenOrderRefundEntity entity) throws Exception {
        int flag = 0; //数据库处理结果
        boolean okSum = false; //是否退款成功
        JSONObject json = new JSONObject();
        //查询订单相关信息
        XeVenOrderInfoEntity orderInfo = afterSaleService.queryOrderInfoByOrderId(entity.getOrderId(),entity.getUserCode());
        BigDecimal freAmount = null==entity.getFreAmount()?new BigDecimal(0):entity.getFreAmount();
        BigDecimal refundMoney = Money.of(entity.getRealRefundedAmount()).plus(freAmount).toStoreDecimal();
        log.info("退款（微信支付）请求易支付开始：订单号={}，退款单号={}，退款金额={}",
                orderInfo.getMainOrderId(),entity.getRefundCode(),refundMoney.toString());
        String str =
                epayService.refundMoneyByWebChat(orderInfo.getOrderId(),entity.getRefundCode(),
                		refundMoney.toString(),entity.getRefundType());
        log.info("退款（微信支付）易支付返回结果：str={}",str);
        if (null != str){
                json = JSONObject.fromObject(str);
                if(json.get("resultCode").toString().equals("0000")){
                    //如果退款成功，更新退款单状态
                    entity.setRefundStatus(VenOrderRefundStatusEnum.DOING.getValue());
                    flag = writeMapper.updateByOrderRefundInfo(entity);
                    //更新成功
                    if(flag>0){
                        okSum = true;
                    }
                }
            }
        return okSum;
    }

    /**
     * @Author:chenjing
     * @Description:非微信支付单条退款
     * @Date:10:51 2017/8/7
     * @params: * @param null
     * @return:
     */
    @Override
    public boolean refundByOnlinePay(XeVenOrderRefundEntity entity) throws Exception {
        int flag = 0; //数据库处理结果
        boolean okSum = false; //是否退款成功
        JSONObject json = new JSONObject();
        //查询订单相关信息
        XeVenOrderInfoEntity orderInfo = afterSaleService.queryOrderInfoByOrderId(entity.getOrderId(),entity.getUserCode());
        BigDecimal freAmount = null==entity.getFreAmount()?new BigDecimal(0):entity.getFreAmount();
        BigDecimal refundMoney = Money.of(entity.getRealRefundedAmount()).plus(freAmount).toStoreDecimal();
        log.info("退款（非微信支付）请求易支付开始：订单号={}，买家易支付账号={}，退款单号={}，退款金额={}",
                orderInfo.getMainOrderId(),orderInfo.getLoginAccount(),entity.getRefundCode(),refundMoney.toString());
        String str =
                epayService.refundMoney(orderInfo.getOrderId(),orderInfo.getLoginAccount(),
                		entity.getRefundCode(),refundMoney.toString(),entity.getRefundType());
        log.info("退款（非微信支付）易支付返回结果：str={}",str);
        if (null != str){
            json = JSONObject.fromObject(str);
            if(json.get("resultCode").toString().equals("0000")){
                //如果退款成功，更新退款单状态
                entity.setRefundStatus(VenOrderRefundStatusEnum.DOING.getValue());
                flag = writeMapper.updateByOrderRefundInfo(entity);
                //更新成功
                if(flag>0){
                    okSum = true;
                }
            }
        }
        return okSum;
    }

    /**
     * @Author:chenjing
     * @Description: 售后创建退款单-同意退款 直接修改状态为退款成功
     * @Date:11:06 2017/9/11
     * @params: * @param null
     * @return:
     */
    @Override
    public int refundByAfterSale(XeVenOrderRefundEntity entity) throws Exception {
        // TODO: 2017/6/29 0029 插入退款单更新日志
        return writeMapper.updateByOrderRefundInfo(entity);
    }

    /**
     * @Author:chenjing
     * @Description:在线支付手动同步状态
     * @Date:20:12 2017/9/6
     * @params: * @param null
     * @return:
     */
    @Override
    public Map queryRefundMoneyDetailByOnline(XeVenOrderRefundEntity entity) throws Exception {
        int flag = 0; //数据库处理结果
        int okFlag = 1; //是否退款成功 1=失败 2=成功
        JSONObject json = new JSONObject();
        Map map = new HashedMap();
        //查询订单相关信息
        XeVenOrderInfoEntity orderInfo = afterSaleService.queryOrderInfoByOrderId(entity.getOrderId(),entity.getUserCode());
        log.info("手动同步状态(在线支付)请求易支付开始：订单号={}，退款单号={}",orderInfo.getMainOrderId(),entity.getRefundCode());
        String str =
                epayService.queryRefundMoneyOnlineDetail(orderInfo.getMainOrderId());
        log.info("手动同步接口（在线支付）易支付返回结果,str={}",str);
        if (null != str){
            /**
            if(str.contains("504")){
                log.error("手动同步接口（在线支付）易支付外部接口异常！");
                map.put("msg","同步失败！");
                map.put("okFlag","1");
                return map;
            }
             **/
            json = JSONObject.fromObject(str);
            if(json.get("resultCode").toString().equals("200")){
                String status = JSONObject.fromObject(json.get("resultMsg")).get("status").toString();
                if ("4".equals(status) || "5".equals(status)){
                    //如果退款成功，更新退款单状态
                    entity.setRefundStatus(VenOrderRefundStatusEnum.DONE.getValue());
                    entity.setRefundDate(new Date());
                    flag = writeMapper.updateByOrderRefundInfo(entity);
                    //更新成功
                    if(flag>0) {
                        map.put("msg","退款成功！");
                        map.put("okFlag","2");
                    }else {
                        map.put("msg","更新失败！");
                        map.put("okFlag","1");
                    }
                }else if("2".equals(status)){
                    //处理中
                    map.put("msg","退款处理中！");
                    map.put("okFlag","2");
                }else if("3".equals(status)){
                    //退款失败
                    entity.setRefundStatus(VenOrderRefundStatusEnum.FAILED.getValue());
                    flag = writeMapper.updateByOrderRefundInfo(entity);
                    //更新成功
                    if(flag>0) {
                        map.put("msg","退款失败！");
                        map.put("okFlag","2");
                    }else {
                        map.put("msg","更新失败！");
                        map.put("okFlag","1");
                    }
                }
            }
        }
        return map;
    }
    /**
     * 完成退款
     * @author: 李贝贝
     * @createTime: 2018年6月13日 下午1:43:49  
     * @history:  
     * @param entity
     * @return int
     */
    public int finishRefund(XeVenOrderRefundEntity entity){
    	int flag = writeMapper.updateByOrderRefundInfo(entity);
    	return flag;
    }
}
